home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 15 / CU Amiga Magazine's Super CD-ROM 15 (1997)(EMAP Images)(GB)[!][issue 1997-10].iso / CUCD / Graphics / Ghostscript / source / gdevlj56.c < prev    next >
C/C++ Source or Header  |  1997-01-30  |  8KB  |  270 lines

  1. /* Copyright (C) 1997 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of Aladdin Ghostscript.
  4.   
  5.   Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  6.   or distributor accepts any responsibility for the consequences of using it,
  7.   or for whether it serves any particular purpose or works at all, unless he
  8.   or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  9.   License (the "License") for full details.
  10.   
  11.   Every copy of Aladdin Ghostscript must include a copy of the License,
  12.   normally in a plain ASCII text file named PUBLIC.  The License grants you
  13.   the right to copy, modify and redistribute Aladdin Ghostscript, but only
  14.   under certain conditions described in the License.  Among other things, the
  15.   License requires that the copyright notice and this notice be preserved on
  16.   all copies.
  17. */
  18.  
  19. /* gdevlj56.c */
  20. /* H-P LaserJet 5 & 6 drivers for Ghostscript */
  21. #include "gdevprn.h"
  22. #include "gdevpcl.h"
  23. #include "gdevpxat.h"
  24. #include "gdevpxen.h"
  25. #include "gdevpxop.h"
  26.  
  27. /* Define the default resolution. */
  28. #ifndef X_DPI
  29. #  define X_DPI 600
  30. #endif
  31. #ifndef Y_DPI
  32. #  define Y_DPI 600
  33. #endif
  34.  
  35. /* Define the number of blank lines that make it worthwhile to */
  36. /* start a new image. */
  37. #define MIN_SKIP_LINES 2
  38.  
  39. /* We round up the LINE_SIZE to a multiple of a ulong for faster scanning. */
  40. #define W sizeof(word)
  41.  
  42. private dev_proc_open_device(ljet5_open);
  43. private dev_proc_close_device(ljet5_close);
  44. private dev_proc_print_page(ljet5_print_page);
  45.  
  46. private gx_device_procs ljet5_procs =
  47.   prn_procs(ljet5_open, gdev_prn_output_page, ljet5_close);
  48.  
  49. gx_device_printer far_data gs_lj5mono_device =
  50.   prn_device(ljet5_procs, "lj5mono",
  51.     DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
  52.     X_DPI, Y_DPI,
  53.     0, 0, 0, 0,
  54.     1, ljet5_print_page);
  55.  
  56. private gx_device_procs lj5gray_procs =
  57.   prn_color_procs(ljet5_open, gdev_prn_output_page, ljet5_close,
  58.           gx_default_gray_map_rgb_color,
  59.           gx_default_gray_map_color_rgb);
  60.  
  61. gx_device_printer far_data gs_lj5gray_device = {
  62.   prn_device_body(gx_device_printer, lj5gray_procs, "lj5gray",
  63.     DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
  64.     X_DPI, Y_DPI,
  65.     0, 0, 0, 0,
  66.     1, 8, 255, 0, 256, 1, ljet5_print_page)
  67. };
  68.  
  69. #define ppdev ((gx_device_printer *)pdev)
  70.  
  71. /* Write a 'canned' data sequence. */
  72. #define fwrite_bytes(bytes, strm) fwrite(bytes, 1, sizeof(bytes), strm)
  73.  
  74. /* Utilities for writing data values. */
  75. /* H-P printers only support little-endian data, so that's what we emit. */
  76. #define da(a) pxt_attr_ubyte, (a)
  77. private void
  78. put_a(px_attribute_t a, FILE *prn_stream)
  79. {    fputc(pxt_attr_ubyte, prn_stream);
  80.     fputc(a, prn_stream);
  81. }
  82. #define dub(b) pxt_ubyte, (byte)(b)
  83. #define ds(i) (byte)(i), (byte)((i) >> 8)
  84. private void
  85. put_s(uint i, FILE *prn_stream)
  86. {    fputc((byte)i, prn_stream);
  87.     fputc((byte)(i >> 8), prn_stream);
  88. }
  89. #define dus(i) pxt_uint16, ds(i)
  90. private void
  91. put_us(uint i, FILE *prn_stream)
  92. {    fputc(pxt_uint16, prn_stream);
  93.     put_s(i, prn_stream);
  94. }
  95. #define dusp(ix,iy) pxt_uint16_xy, ds(ix), ds(iy)
  96. private void
  97. put_usp(uint ix, uint iy, FILE *prn_stream)
  98. {    fputc(pxt_uint16_xy, prn_stream);
  99.     put_s(ix, prn_stream);
  100.     put_s(iy, prn_stream);
  101. }
  102. #define dss(i) pxt_sint16, ds(i)
  103. private void
  104. put_ss(int i, FILE *prn_stream)
  105. {    fputc(pxt_sint16, prn_stream);
  106.     put_s((uint)i, prn_stream);
  107. }
  108. #define dl(l) ds(l), ds((l) >> 16)
  109. private void
  110. put_l(ulong l, FILE *prn_stream)
  111. {    put_s((uint)l, prn_stream);
  112.     put_s((uint)(l >> 16), prn_stream);
  113. }
  114.  
  115. /* Open the printer, writing the stream header. */
  116. private int
  117. ljet5_open(gx_device *pdev)
  118. {    int code = gdev_prn_open(pdev);
  119.  
  120.     if ( code < 0 )
  121.       return code;
  122.     code = gdev_prn_open_printer(pdev, true);
  123.     if ( code < 0 )
  124.       return code;
  125.     { FILE *prn_stream = ppdev->file;
  126.       static const byte stream_header[] = {
  127.         da(pxaUnitsPerMeasure),
  128.         dub(0), da(pxaMeasure),
  129.         dub(eErrorPage), da(pxaErrorReport),
  130.         pxtBeginSession,
  131.         dub(0), da(pxaSourceType),
  132.         dub(eBinaryLowByteFirst), da(pxaDataOrg),
  133.         pxtOpenDataSource
  134.       };
  135.  
  136.       fputs("\033%-12345X@PJL ENTER LANGUAGE = PCLXL\n", prn_stream);
  137.       fputs(") HP-PCL XL;1;1\n", prn_stream);
  138.       put_usp((uint)(pdev->HWResolution[0] + 0.5),
  139.           (uint)(pdev->HWResolution[1] + 0.5), prn_stream);
  140.       fwrite_bytes(stream_header, prn_stream);
  141.     }
  142.     return 0;
  143. }
  144.  
  145. /* Close the printer, writing the stream trailer. */
  146. private int
  147. ljet5_close(gx_device *pdev)
  148. {    int code = gdev_prn_open_printer(pdev, true);
  149.  
  150.     if ( code < 0 )
  151.       return code;
  152.     { FILE *prn_stream = ppdev->file;
  153.       static const byte stream_trailer[] = {
  154.         pxtCloseDataSource,
  155.         pxtEndSession,
  156.         033, '%', '-', '1', '2', '3', '4', '5', 'X'
  157.       };
  158.  
  159.       fwrite_bytes(stream_trailer, prn_stream);
  160.     }
  161.     return gdev_prn_close(pdev);
  162. }
  163.  
  164. /* Send the page to the printer.  For now, just send the whole image. */
  165. private int
  166. ljet5_print_page(gx_device_printer *pdev, FILE *prn_stream)
  167. {    uint line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
  168.     uint line_size_words = (line_size + W - 1) / W;
  169.     uint out_size = line_size + (line_size / 127) + 1;
  170.     word *line = (word *)gs_malloc(line_size_words, W, "ljet5(line)");
  171.     byte *out = gs_malloc(out_size, 1, "ljet5(out)");
  172.     int code = 0;
  173.     int lnum;
  174.  
  175.     if ( line == 0 || out == 0 )
  176.       { code = gs_note_error(gs_error_VMerror);
  177.         goto done;
  178.       }
  179.  
  180.     /* Write the page header. */
  181.     { static const byte page_header[] = {
  182.         dub(ePortraitOrientation), da(pxaOrientation),
  183.         dub(eLetterPaper), da(pxaMediaSize),
  184.         dub(eAutoSelect), da(pxaMediaSource),
  185.         pxtBeginPage,
  186.         dusp(0, 0), da(pxaPoint),
  187.         pxtSetCursor
  188.       };
  189.       static const byte mono_header[] = {
  190.         dub(eGray), da(pxaColorSpace),
  191.         dub(e8Bit), da(pxaPaletteDepth),
  192.         pxt_ubyte_array, pxt_ubyte, 2, 0xff, 0x00, da(pxaPaletteData),
  193.         pxtSetColorSpace
  194.       };
  195.       static const byte gray_header[] = {
  196.         dub(eGray), da(pxaColorSpace),
  197.         pxtSetColorSpace
  198.       };
  199.  
  200.       fwrite_bytes(page_header, prn_stream);
  201.       if ( pdev->color_info.depth == 1 )
  202.         fwrite_bytes(mono_header, prn_stream);
  203.       else
  204.         fwrite_bytes(gray_header, prn_stream);
  205.     }
  206.  
  207.     /* Write the image header. */
  208.     { static const byte mono_image_header[] = {
  209.         da(pxaDestinationSize),
  210.         dub(eIndexedPixel), da(pxaColorMapping),
  211.         dub(e1Bit), da(pxaColorDepth),
  212.         pxtBeginImage
  213.       };
  214.       static const byte gray_image_header[] = {
  215.         da(pxaDestinationSize),
  216.         dub(eDirectPixel), da(pxaColorMapping),
  217.         dub(e8Bit), da(pxaColorDepth),
  218.         pxtBeginImage
  219.       };
  220.  
  221.       put_us(pdev->width, prn_stream);
  222.       put_a(pxaSourceWidth, prn_stream);
  223.       put_us(pdev->height, prn_stream);
  224.       put_a(pxaSourceHeight, prn_stream);
  225.       put_usp(pdev->width, pdev->height, prn_stream);
  226.       if ( pdev->color_info.depth == 1 )
  227.         fwrite_bytes(mono_image_header, prn_stream);
  228.       else
  229.         fwrite_bytes(gray_image_header, prn_stream);
  230.     }
  231.  
  232.     /* Write the image data, compressing each line. */
  233.     for ( lnum = 0; lnum < pdev->height; ++lnum )
  234.       { int ncompr;
  235.         static const byte line_header[] = {
  236.           da(pxaStartLine),
  237.           dus(1), da(pxaBlockHeight),
  238.           dub(eRLECompression), da(pxaCompressMode),
  239.           pxtReadImage
  240.         };
  241.  
  242.         code = gdev_prn_copy_scan_lines(pdev, lnum, (byte *)line, line_size);
  243.         if ( code < 0 )
  244.           goto fin;
  245.         put_us(lnum, prn_stream);
  246.         fwrite_bytes(line_header, prn_stream);
  247.         ncompr = gdev_pcl_mode2compress(line, line + line_size_words, out);
  248.         if ( ncompr <= 255 )
  249.           { fputc(pxt_dataLengthByte, prn_stream);
  250.             fputc(ncompr, prn_stream);
  251.           }
  252.         else
  253.           { fputc(pxt_dataLength, prn_stream);
  254.             put_l(ncompr, prn_stream);
  255.           }
  256.         fwrite(out, 1, ncompr, prn_stream);
  257.       }
  258.  
  259.     /* Finish up. */
  260. fin:
  261.     fputc(pxtEndImage, prn_stream);
  262.     fputc(pxtEndPage, prn_stream);
  263. done:
  264.     if ( out )
  265.       gs_free(out, out_size, 1, "ljet5(out)");
  266.     if ( line )
  267.       gs_free(line, line_size_words, W, "ljet5(out)");
  268.     return code;
  269. }
  270.